class MathUtils {
  /**
   * 计算两个数的最大公约数
   * @param {number} a - 第一个数
   * @param {number} b - 第二个数
   * @returns {number} 最大公约数
   */
  static gcd(a:number, b:number):number {
    if (b === 0) return a
    return this.gcd(b, a % b)
  }

  /**
   * 计算两个数的最小公倍数
   * @param {number} a - 第一个数
   * @param {number} b - 第二个数
   * @returns {number} 最小公倍数
   */
  static lcm(a:number, b:number):number {
    return (a * b) / this.gcd(a, b)
  }

  /**
   * 生成指定范围内的随机整数
   * @param {number} min - 最小值
   * @param {number} max - 最大值
   * @returns {number} 随机整数
   */
  static getRandomInt(min:number, max:number):number {
    return Math.floor(Math.random() * (max - min + 1)) + min
  }

  /**
   * 计算数组的和
   * @param {Array<number>} arr - 数字数组
   * @returns {number} 数组的和
   */
  static sum(arr:Array<number>):number {
    return arr.reduce((total, num) => total + num, 0)
  }

  /**
   * 计算数组的方差
   * @param {Array<number>} arr - 数字数组
   * @returns {number} 方差
   */
  static variance(arr:Array<number>):number {
    const mean = this.average(arr)
    return this.sum(arr.map((num) => (num - mean) ** 2)) / arr.length
  }

  /**
   * 计算数组的平均值
   * @param arr 数字数组
   * @returns {number} 平均值
   */
  static average(arr: number[]): number {
    if (arr.length === 0) return 0;
    return this.sum(arr) / arr.length;
  }

  /**
   * 计算数组的标准差
   * @param {Array<number>} arr - 数字数组
   * @returns {number} 标准差
   */
  static standardDeviation(arr:Array<number>): number {
    return Math.sqrt(this.variance(arr))
  }

  /**
   * 计算两个数的和
   * @param {number} a - 第一个数
   * @param {number} b - 第二个数
   * @returns {number} 和
   */
  static add(a: number, b: number): number {
    return this.toFixed(a + b)
  }

  /**
   * 计算两个数的差
   * @param {number} a - 第一个数
   * @param {number} b - 第二个数
   * @returns {number} 差
   */
  static subtract(a: number, b: number): number {
    return this.toFixed(a - b)
  }

  /**
   * 计算两个数的积
   * @param {number} a - 第一个数
   * @param {number} b - 第二个数
   * @returns {number} 积
   */
  static multiply(a: number, b: number): number {
    return this.toFixed(a * b)
  }

  /**
   * 计算两个数的商
   * @param {number} a - 第一个数
   * @param {number} b - 第二个数
   * @returns {number} 商
   * @throws {Error} 如果第二个数为零
   */
  static divide(a: number, b: number): number {
    if (b === 0) {
      throw new Error('Division by zero is not allowed.')
    }
    return this.toFixed(a / b)
  }

  /**
   * 将数值四舍五入到指定的小数位数
   * @param {number} num - 要四舍五入的数字
   * @param {number} [decimals=2] - 小数位数，默认为2
   * @returns {number} 四舍五入后的数字
   */
  static toFixed(num: number, decimals: number = 2): number {
    return Number(num.toFixed(decimals))
  }
}

export default MathUtils
